Esercizi di "Lettura"

Da aptiva.

Chi ha difficolta' a scrivere codice Python puo' provare a fare questi esercizi di "lettura" di codice Python.

Gli esercizi proposti sono programmi funzionanti.

Come svolgimento dell'esercizio si deve:

  • determinare lo scopo del programma
  • spiegare il significato di ogni riga (non banale) del codice

Indice

1

def dd(s):
  d,m,y=s.split('.')
  d,m,y=int(d),int(m),int(y)
  md=[0,31,28,31,30,31,30,31,31,30,31,30,31]
  if y % 4 == 0: md[2]=29
  dy=d
  for i in range(1,m):
    dy += md[i]
  return dy

if __name__=="__main__":
  data=input("Dammi una data (es. 14.03.2014) ")
  print("il risultato della funzione misteriosa e' ",dd(data))

Esercizio svolto da Silvia. Nell’esercizio numero uno: - viene definita una funzione che si chiama dd e una variabile di input chiamata (s)e ciò che segue è dipendente - abbiamo tre sottostringhe chiamate d (day), m (month), year (y)= s.split (‘.’) converte una stringa in una lista di stringhe cioè le date vengono divise con un puntino - d,m,y sono numeri interi - md è una lista che contiene partendo dallo 0 i numeri dei giorni dei mesi da gennaio a dicembre - se l’anno è un multiplo di 4 sostituisco al mese numero 2 (febbraio) il numero 29 - dy è una nuova variabile indica il giorno - for i in range (1,m) è un ciclo che va da 1 al mese inserito ad esempio al 14/03/2014 sarà for in range (1,3) - dy+= md [i] i=1 i=2 i=3 - return dy Termina la funzione e mi restituisce il valore dei giorni dalla data indicata fino all’inizio dell’anno ovvero saranno 14 giorni di marzo, 29 febbraio, 31 gennaio per un totale di 74 giorni.

Commenti alla soluzione (rd 30.05). La soluzione e' quasi perfetta. L'unico commento riguarda la spiegazione di range(1,3), in questo caso i loop viene effettuato per i=1 e i=2 ma non i=3. Infatti e' corretto cosi'. Se vogliamo sapere quanti giorni sono trascorsi dall'inizio dell'anno fino al 14 marzo dobbiamo sommare i giorni di gennaio e febbraio (mesi interamente trascorsi) e i 14 giorni di marzo. Il fatto che marzo abbia 31 giorni e' ininfluente nel calcolo dei giorni fino al 14 marzo.

2

def imin(l):
  im,mn=0,l[0]
  for i in range(1,len(l)):
    if l[i]<mn: im,mn=i,l[i]
  return im

if __name__="__main__":
  l=input('dammi in input una lista di elementi (es: [1,2,3]): ')
  print("l'output della funzione misteriosa e': ",imin(l))

Esercizio di lettura numero 2 – svolto da Silvia

Viene definita una funzione imin con variabile l e ciò che segue è dipendente. im, mn hanno valore 0 e l e il primo valore che assegno a im è 0. Segue for i in range (1,len(l)): è un ciclo da 1 alla lunghezza l (numero di elementi inseriti) se l’elemento con indice 1 è <dell’elemento con indice 0 allora a im assegno il valore di i (1) e mn assegno sempre il valore dell’elemento con indice i (1). Il valore ritornato dalla funzione è il contenuto della variabile im. Il procedimento si ripete per i che va da 1al numero di elementi inseriti. Se i numeri sono ordinati in numero crescente il risultato della funzione è sempre 0.

rd (3 giugno h 15): e' quasi arrivata al risultato... occorre astrarre un po'. Se i numeri sono in ordine crescente ritorna 0. Questa risposta e' perfetta. E se fossero in ordine decrescente che numero verrebbe ritornato? Esaminiamo ora una lista qualsiasi, non ordinata. Se io usassi il valore di ritorno della funzione come indice nella lista, che proprieta' avrebbe l'elemento cosi' individuato?

Silvia: Se è in ordine decrescente mi ritorna l'ultimo della lista in cui c'è il numero più piccolo. Se invece, non è ordinata mi restituisce l'indice della cella contenente il numero più piccolo. Tutto questo l'ho provato su cartaceo per ora perché non ho avuto tempo su python. Lo farò in seguito.

rd (4 giugno): e' esattamente questo lo scopo della funzione imin (indice del minimo).

3

def r13(s):
        e=''
        for c in s:
                if 'A'<=c<='Z':
                        e+=chr(((ord(c)-ord('A'))+13)%26+ord('A'))
                elif 'a'<=c<='z':
                        e+=chr(((ord(c)-ord('a'))+13)%26+ord('a'))
                else:
                        e+=c
        return e

if __name__=="__main__":
        s=input("scrivi una semplice frase (es: 'Ciao Mondo') ")
        r=r13(s)
        print("il risultato della funzione misteriosa e': ",r)
        print("consiglio: prova a eseguire nuovamente il programma scrivendo")
        print("la frase: ",r)

Alice B. Provando la funzione, spiegherei così il procedimento: data una stringa-una frase in input, si applichi la funzione r(13). La funzione dice che per ogni lettera ('c') maiuscola che compone la frase, si converta la lettera in numero ordinale secondo la posizione che ha nell'alfabeto e rispetto alla lettera A, basandosi sulla codifica ASCII (in base 26), si aggiunga 13 al numero ottenuto, poi, sempre in base 26 cioè alle lettere dell'alfabeto inglese, si applichi la formula opposta (chr), di riconversione del numero ordinale in lettera corrispondente. Fa lo stesso procedimento per ogni lettera 'c' minuscola. Altrimenti, se il carattere contenuto nella frase non è alfabetico, e+=c, cioè riscrivere nella frase lo stesso carattere. La funzione restituisce una frase che si sostituisce alla precedente, secondo la funzione r13, mantenendo i caratteri MAIUSCOLI e minuscoli, che, partendo dalla posizione precedente aggiunge 13 a ciascuna lettera, dando in output corrispondenti lettere aumentate di 13 posizioni nell'alfabeto. (es: Ciao Mondo += Pvnb Zbaqb) Si potrebbe dire che Python stampa una frase con lettere maiuscole e minuscole sostituite in chiave 13 (una criptazione).

4

def pf(n):
        f=[]
        for i in range(2,n+1):
                while n % i == 0:
                        f.append(i)
                        n //= i
                if n == 1:
                        break
        return f

if __name__=="__main__":
        n=int(input("dammi un numero (consigliato da 2 a 1000): "))
        print("il risultato della funzione misteriosa e' ",pf(n))

Alice B. La funzione scompone in fattori primi un numero, da 2 a 1000. Viene creata la lista f, vuota. Per ogni variabile i, che contiene tutti gli interi che vanno da 2 a n (n+1 è escluso), fintanto che il numero n è divisibile per i,(con i che va appunto da 2 a n), -cioè ho resto 0-, 'appendi' i nella lista f. Poi restituisci il numero n diviso i. Il ciclo continua, finché il numero n è uguale a 1, cioè fintanto che n assume un valore che diviso se stesso da 1. Quando n assume valore 1, la funzione si ferma. La funzione ritorna f, che è la lista dalla scomposizione in numeri primi di n. rd: 05 giugno. E' esatto.

5

(richiede il modulo turtle)

def cy(r):
        turtle.setup(400,400)
        turtle.penup()
        turtle.hideturtle()
        turtle.speed(0)
        for i in range(1000):
                x,y=random.randint(-200,200),random.randint(-200,200)
                if (x*x+y*y)**0.5 < r:
                        color="red"
                else:
                        color="blue"
                turtle.goto(x,y)
                turtle.dot(5,color)

if __name__=="__main__":
        r=float(input("scrivi un numero (consigliato da 100 a 200): "))
        print("guarda il risultato della funzione misteriosa")
        cy(r)
        turtle.exitonclick()

6

(richiede il modulo turtle)

import turtle

def poly(n):
        for i in range(n):
                turtle.forward(50)
                turtle.left(360/n)

if __name__=="__main__":
        n=int(input("dammi un intero (consigliato da 3 a 12): "))
        poly(n)
        turtle.exitonclick()

Commento Cati: Si crea la funzione poly (nome liberamente per definire la funzione, in questo caso l'abbreviazione di poligono), contenente la variabile n tra parentesi.Il carattere due punti che seguono indicano che sta per iniziare una identazione, ovvero una serie(o blocco) di azioni seguenti che fanno parte della funzione stessa. Per ogni i (elemento) appartenente al range di n, ovvero alla numerazione ordinale crescente di n partendo da zero, fino a n. Turtle.forward= vai avanti di 50 punti disegnando (in questo caso una riga, retta), poi "turtle.left(360/n)" gira a sinistra sul nuovo punto(di fine riga) di 360°/n (considerando che la somma degli angoli esterni di un poligono è pari a 360°). Sono poi richesti i valori in input di n consigliando un numero commpreso tra 3 e 12. Si evita 1 perchè sarebbe una semplice retta, il numero 2 perchè effettuando un angolo giro su n+1, ricalcherebbe la riga stessa. Dal numero 3 in poi, crea tutti i poligoni partendo da tre lati. Deduco non oltre il numero 13, perchè la figura tende a uscire nella sua costruzione, dal monitor.

7

Questo e' contorto. Se vi piace... iniziate a preoccuparvi: state diventando informatici ;-)

f="f={0}{1}{0};print(f.format(chr(34),f))";print(f.format(chr(34),f))

NB: non e' necessario capire questo programma, e' solo per chi si vuole cimentare in una sfida...

8

def pf(n):
        f=[]
        for i in range(2,n+1):
                while n % i == 0:
                        f.append(i)
                        n //= i
                if n == 1:
                        break
        return f

def fgcd(a,b):
        def rgcd(fa,fb):
                if fa and fb:
                        if fa[0]==fb[0]:
                                return fa[:1]+rgcd(fa[1:],fb[1:])
                        elif fa[0]<fb[0]:
                                return rgcd(fa[1:],fb)
                        else:
                                return rgcd(fa,fb[1:])
                else:
                        return []
        return rgcd(pf(a),pf(b))

def flcm(a,b):
        def rlcm(fa,fb):
                if fa and fb:
                        if fa[0]==fb[0]:
                                return fa[:1]+rlcm(fa[1:],fb[1:])
                        elif fa[0]<fb[0]:
                                return fa[:1]+rlcm(fa[1:],fb)
                        else:
                                return fa[:1]+rlcm(fa,fb[1:])
                else:
                        return fa if fa else fb
        return rlcm(pf(a),pf(b))

def mul(l):
        rv=1
        for el in l:
                rv *= el
        return rv

def gcd(x,y):
        return mul(fgcd(x,y))

def lcm(x,y):
        return mul(flcm(x,y))

if __name__=="__main__":
        a,b=input("Inserisci due numeri (es: 48 36): ").split()
        a,b=int(a),int(b)
        print("pf({})={}".format(a,pf(a)))
        print("pf({})={}".format(b,pf(b)))
        print("fgcd({},{})={}".format(a,b,fgcd(a,b)))
        print("flcm({},{})={}".format(a,b,flcm(a,b)))
        print("gcd({},{})={}".format(a,b,gcd(a,b)))
        print("lcm({},{})={}".format(a,b,lcm(a,b)))

Lettura svolta da A.Bellan La funzione def pf(n)è restituisce la scomposizione in fattori primi di un numero, con la ripetizione dei fattori uguali e l'ordinamento crescente di essi. Definisce una lista vuota. Per ogni numero (i) che va da 2 a n, fintanto che il numero(n) diviso in numero(i) da come resto 0, appendi (i) nella lista vuota, e poi esegui l'operazione (di assegnazione) n=n/i; se il resto è 1, allora la funzione si ferma (la scomposizione è terminata). La stampa della lista di fattori (quindi del risultato della funzione pf) per ciascun numero, sarà organizzato dalla funzione .format, che restituirà ciascun numero n tra parentesi preceduto da pf a sinistra dell'= e della lista dei fattori a destra dell'uguale separati dalla virgola(,).

La funzione fgcd di a,b (dei 2 numeri), è la funzione che definisce il MCD (Grater Common Den.). Essa chiama una funzione rgcd di fa e di fb, cioè sulle due liste di fattori primi, ricorsiva. Il caso base è quando una delle due liste è vuota (and): allora ritorna la lista vuota. Altrimenti, se il primo elemento della lista a è = al primo elemento della lista b, ritorna l'elemento di a e poi richiama ricorsivamente la funzione per gli elementi successivi delle 2 liste. Altrimenti, se il primo elemento della lista a è minore della lista b, richiama subito la funzione, cioè ricorsione, ma senza il primo elemento (della lista a), o viceversa. La stampa della lista (quindi del risultato della funzione fgcd) per i 2 numeri, sarà organizzato dalla funzione .format, che restituirà i 2 numeri n tra parentesi, divisi dalla virgola, preceduti da fgcd a sinistra dell'= e della lista dei fattori a destra dell'uguale.

La funzione flcm di a,b è la funzione del minimo comune denominatore (mcm). E come la precedente chiama una funzione ricorsiva sulle liste di scomposizione in fattori primi.Il caso base è se una delle due è vuota, allora torna o tutta la lista di a se b è vuota o viceversa. Altrimenti se il primo elemento di a è = al primo di b, allora viene restituito l'elemento di a, più la ricorsione sugli elementi successivi di a gli elementi della lista di b- il primo. Se il primo elemento di a è minore di quello di b, allora viene restituito sempre l'elemento di a, più la ricorsione sugli elementi successivi della lista di a e tutti gli elementi della lista di b (o viceversa). La stampa della lista (quindi del risultato della funzione flcm) per i 2 numeri, sarà organizzato dalla funzione .format, che restituirà i 2 numeri n tra parentesi, divisi dalla virgola, preceduti da flcm a sinistra dell'= e della lista dei fattori a destra dell'uguale.

La funzione def mul(l) restituisce il risultato della moltiplicazione della lista dei fgcd o dei flcm, per ciascun numero. Assunto l'elemento rv=1, per ogni elemento in l, moltiplicare a rv l'elemento el. Il risultato ottenuto, sostituirlo a rv. A rv ottnuto, moltiplicare l'elemento el successivo , nella lista l. La stampa dei prodotti (delle funzioni gcd e lcm) dei 2 numeri n, sarà organizzato dalla funzione .format, che restituirà i 2 numeri n tra parentesi, divisi dalla virgola, preceduti da gcd o lcm a sinistra dell'= e del prodotto dei fattori a destra dell'uguale.

9

def div(n):
        return {x for x in range(1,n+1) if n % x == 0}

#alternativa:
#def div(n):
#       d=set()
#       for x in range(1,n+1):
#               if n % x == 0: d.add(x)
#       return d

def gcd(a,b):
        return max(div(a) & div(b))

def mul(n,limit):
        return {x*n for x in range(1,limit//n + 1)}

#alternativa
#def mul(n,limit):
#       d=set()
#       for x in range(1,limit//n + 1):
#               d.add(x*n)
#       return d

def lcm(a,b):
        return min(mul(a,a*b) & mul(b,a*b))

if __name__=="__main__":
        a,b=input("Inserisci due numeri (es: 48 36): ").split()
        a,b=int(a),int(b)
        print("div({})={}".format(a,div(a)))
        print("div({})={}".format(b,div(b)))
        print("mul({},{})={}".format(a,a*b,mul(a,a*b)))
        print("mul({},{})={}".format(b,a*b,mul(b,a*b)))
        print("gcd({},{})={}".format(a,b,gcd(a,b)))
        print("lcm({},{})={}".format(a,b,lcm(a,b)))

Esercizio n° 9, commentato da '''Domenico''' - Domenica 15 Giugno 2014 - Ore 19:18

def div(n):          return {x for x in range(1,n+1) if n % x == 0}  

Viene definita una funzione che si chiama div. La funzione possiede un parametro in ingresso, che si chiama n. Segue il corpo della funzione. Viene eseguito un ciclo for, con variabile contatore del ciclo (x) che assume valori tra 1 e n+1 compresi ( range(1,n+1) ), ad es. se come param. in input alla funzione abbiamo n = 2. Il ciclo for viene ripetuto 3 volte perchè x assume i valori tra [1,3]. All'interno del ciclo troviamo una condizione if, questa si verifica solo quando il resto della divisione tra il parametro n e il valore x assunto dalla variabile del ciclo è zero. Vengono quindi ritornati dalla funzione un insieme set di valori che verificano n % x == 0.

def gcd(a,b):

       return max(div(a) & div(b))

Viene definita una funzione che si chiama gcd, in input alla funzione ci sono due parametri, a e b, segue il corpo della funzione, che contiene un'unica riga di codice. Questa riga di codice restituisce (return) il massimo tra l'intersezione (&) degli insiemi restituiti dalle chiamate della funzione div aventi parametro a e poi b.


def mul(n,limit):         return {x*n for x in range(1,limit//n + 1)}  


Viene definita una funzione mul con due parametri di nome n e limit, segue il corpo della funzione. Il corpo contiene una sola riga di codice, viene eseguito un ciclo for con variabile x che assume valori nel range [1, limit//n +1), dove l'ultimo valore del ciclo è escluso, il doppio slash rappresenta la divisione tra limit è il parametro n, senza tenere conto dei decimali. L'insieme di valori restituiti quindi dalla funzione sono dati dalla moltiplicazione di x*n.


def lcm(a,b):          return min(mul(a,a*b) & mul(b,a*b))


Viene definita una funzione lcm, che possiede due parametri in input a e b. La funzione restituisce il valore minimo tra l'intersezione degli insiemi restituiti dalle chiamate alle funzioni mul con parametri(a,a*b) e(b,a*b).


10

def sdiv(n):
        return {x for x in range(2,n) if n % x == 0}

#alternativa:
#def sdiv(n):
#       d=set()
#       for x in range(2,n):
#               if n % x == 0: d.add(x)
#       return d

def pr(n):
        return not sdiv(n)

def pdiv(n):
        return {x for x in sdiv(n) if pr(x)}

#alternativa:
#def pdiv(n):
#       d=set()
#       for x in sdiv(n):
#               if pr(x): d.add(x)
#       return d

def gcd(a,b):
        csdiv=pdiv(a) & pdiv(b)
        r=1
        for x in csdiv:
                while a % (r*x) == 0 and b % (r*x) == 0:
                        r *= x
        return r

def lcm(a,b):
        return a * b // gcd(a,b)

if __name__=="__main__":
        a,b=input("Inserisci due numeri (es: 48 36): ").split()
        a,b=int(a),int(b)
        print("pdiv({})={}".format(a,pdiv(a)))
        print("pdiv({})={}".format(b,pdiv(b)))
        print("gcd({},{})={}".format(a,b,gcd(a,b)))
        print("lcm({},{})={}".format(a,b,lcm(a,b)))

11

def tartline(l):
        l[:0]=[1]
        for i in range(1,len(l)-1):
                l[i] += l[i+1]

l=[]
for i in range(12):
        tartline(l)
        print("{:^60}".format(l))

Commento di Cati: Triangolo di Tartaglia Il programma inizia con le creazione della funzione tartline con variabile l (elle). Essendo l[:0] uguale a “ “, si assegna il valore 1, così l’elenco(composto da due valori) inizia e termina con il numero 1 [1,1]. For i in range (l, len(l)-1), per ogni elemento i presente nel range di l e dell’ultimo elmento di l, somma l’elemento “l” al suo numero consegutivo. O meglio, somma ad ogni elemento di “l” il suo numero consegutivo fino all’ultimo numero della lista (che sarà 1). L=[] lista vuota, a cui verranno assegnati i valori calcolati dalla funzione. For i in range(12): per ogni elemento i presente nel range di 12 (quindi 1,2,3,…,11) applica la funzione tartline (sommando i consegutivi) e stampa formattando l’elenco {} con allineamento centrato.

12

def sdiv(n):
        return {x for x in range(2,n) if n % x == 0}

#alternativa:
#def sdiv(n):
#       d=set()
#       for x in range(2,n):
#               if n % x == 0: d.add(x)
#       return d

def pr(n):
        return not sdiv(n)

N=int(input("dammi il numero massimo (es 100): "))
print("ecco i numeri ***** fino a",N,":",[n for n in range(1,N+1) if pr(n)])

Esercizio svolto da Runa:
Il programma prende in input un numero e poi richiama la funzione pr per tutti i numeri da 1 fino al numero passato per stabilire quali numeri sono primi, se il numero controllato non ha divisori allora viene aggiunto alla lista dei numeri da stampare altrimenti non viene aggiunto alla lista e si passa al numero successivo.
La funzione pr resitutisce vero se il numero passato non ha divisori; per stabilire se il numero ha divisori richiama la funzione sdiv la quale restituisce l'insieme dei divisori o nulla, se sdiv restituisce nulla pr restituisce vero.
La funzione sdiv controlla se i numeri da 2 al numero interessato escluso dividono il numero che gli è stato passato come parametro. Se un numero nel ciclo divide il numero passato alla funzione esso viene aggiunto ad un insieme. La funzione restituisce poi l'insieme creato.
Per l'utilità che ha sdiv in questo caso però io lo avrei fatto in questo modo:

def sdiv(n):       
    if (n % 2 != 0):
        for x in range(3, int(math.sqrt(n)+1)):
            if n % x == 0:
                return True
            x+=1
    return False

rd: l'idea e' ottima. La funzione (mia) sdiv e' di uso piu' generale e restituisce tutti i divisori significativi del numero (tranne cioe' 1 e il numero stesso). E' giusta l'osservazione che e' sprecata per verificare se un numero e' primo o meno. la sdiv scritta qui sopra pero' non funziona correttamente, probabilmente e' rimasto un x+=1 da una versione precedente. (non capisco perche' trattare il fattore 2 come caso speciale...) Io piu' che riscrivere la sdiv, riscriverei la pr nel modo:

def pr(n):      
        for x in range(2, int(n**(0.5)+1)):
                if n % x == 0:
                        return False
        return True

Per completezza la versione della sdiv proposta da Ruta (rivista e corretta) e':

import math
def sdiv(n):      
    for x in range(2, int(math.sqrt(n)+1)):
            if n % x == 0:
                return True
    return False

13

vf=[("Nella vecchia fattoria","Quante bestie ha zio Tobia","C'e' la capra","capra","ca"),
        ("Attaccato a un carrettino","C'è un quadrupede piccino","L'asinel","nel","nè"),
        ("Tra le casse e i ferri rotti", "Dove i topi son grassotti","C'è un bel gatto","gatto","ga"),
        ("Tanto grasso e tanto grosso", "Sempre sporco a più non posso", "C'è il maiale","iale","ia"),
        ("Poi sull'argine del fosso", "Alle prese con un osso", "C'è un bel cane","cane","ca"),
        ("Nella stalla silenziosa", "Dopo aver mangiato a iosa", "Dorme il bue","bue","bu")]
refrain="ia ia o"

def recverse(m,n):
        v1,v2,an1,an2,an3=vf[m]
        if n==m:
                print(v1,refrain)
                print(v2,refrain)
        else:
                recverse(m+1,n)
        print(an1,an2,an3,an3,an2)

for i in range(len(vf)):
        recverse(0,i)
        print(vf[0][0],refrain)
        print()


Commento di Silvia
Abbiamo definito una lista (vf) composta da 6 elementi che nello specifico sono tuple, ognuna delle quali è composta da 5 stringhe. Da un punto di vista pratico in ogni tupla ci sono le 5 frasi base per le 6 strofe della filastrocca “Nella vecchia Fattoria”. La variabile refrain è la stringa “ia ia o”. Chiamiamo, per ogni strofa, i primi due versi v1 e v2, e i tre antecedenti an1, an2 e an3 (come si evince dal programma), in particolare indichiamo con v1_0 v1 della primaStrofa, etc.
Dall’esecuzione del programma si evince che a partire dalla lista (vf) si costruisce la filastrocca nel seguente modo:

Strofa 1:
v1_0 refrain v2_0 refrain an1_0 an2_0 an3_0 an3_0 an2_0
v1_0 refrain (a capo)
Strofa 2:
v1_1 refrain v2_1 refrain an1_1 an2_1 an3_1 an3_1 an2_1
an1_0 an2_0 an3_0 an3_0 an2_0
v1_0 refrain (a capo)
Strofa 3:
v1_2 refrain v2_2 refrain an1_2 an2_2 an3_2 an3_2 an2_2
an1_1 an2_1 an3_1 an3_1 an2_1
an1_0 an2_0 an3_0 an3_0 an2_0
v1_0 refrain (a capo)


In parole povere ogni strofa viene costruita in due parti: Parte Base e Parte Ricorsiva.
La Parte Base è data dal verso1 “ia ia o” verso2 … (v1_i refrain v2_i refrain an1_i an2_i an3_i an3_i an2_i), mentre la parte ricorsiva consente la stampa degli antecedenti delle strofe precedenti a ritroso fino alla prima strofa. Alla fine di ogni strofa viene stampato il primo verso della prima strofa (“Nella vecchia fattoria”), poi refrain (“ia ia o”) e quindi si va a capo.
Commento al codice:
Nel main abbiamo un ciclo for con la variabile i che va da 0 alla lunghezza (len(vf)) della lista vf ; nel ciclo si richiama la funzione recverse passando i valori 0 e i, quindi si stampa l’elemento di posizione 0 della tupla di posizione 0 della lista (vf[0][0],), poi refrain e quindi si va a capo (con print()).


Viene definita (def) la funzione recverse con variabili di input m ed n. E’ una funzione ricorsiva che ha l’obiettivo di costruire una strofa di posizione n con gli antecedenti delle strofe precedenti fino alla strofa di posizione m. Il caso base è recverse(n,n), cioè quando n = = m, in tal caso la funzione stampa la “Parte Base” della strofa di posizione n (print(v1,refrain) print(v2,refrain) print(an1,an2,an3,an3,an2)). La chiamata ricorsiva è nella parte else recverse(m+1,n), dove si richiama la funzione con la prima variabile di input incrementata di 1, cioè la costruzione della strofa di posizione n con gli antecedenti fino alla strofa di posizione m+1.

14

import turtle

def hser(size, level):
        if level==0:
                turtle.forward(size)
        else:
                hser(size,level-1)
                turtle.left(45)
                turtle.forward(size * 2**0.5)
                turtle.left(45)
                hser(size,level-1)
                turtle.right(90)
                turtle.forward(size)
                turtle.right(90)
                hser(size,level-1)
                turtle.left(45)
                turtle.forward(size * 2**0.5)
                turtle.left(45)
                hser(size,level-1)

def ser(size, level):
        turtle.penup()
        pos=(2**(level+2)-3) * size // 2 #posizione iniziale
        turtle.setpos(-pos,pos)
        turtle.pendown()
        hser(size,level)
        turtle.right(90)
        hser(size,level)
        turtle.right(90)
        hser(size,level)
        turtle.right(90)
        hser(size,level)
        turtle.right(90)

turtle.speed(0)
turtle.hideturtle()
ser(2,1)
ser(2,2)
ser(2,3)
ser(2,4)
turtle.exitonclick()

15

import turtle
import colorsys
import sys

def arrowstep(level, length, angle):
        if level:
                arrowstep(level-1, length/2, -angle)
                turtle.left(angle)
                arrowstep(level-1, length/2, angle)
                turtle.left(angle)
                arrowstep(level-1, length/2, -angle)
        else:
                turtle.forward(length)

def arrow(level, length):
        if level & 1:
                turtle.left(60)
                arrowstep(level, length, -60)
        else:
                arrowstep(level, length, -60)

turtle.speed(0)
turtle.hideturtle()
turtle.colormode(1)
nmax=6
width=256
xmin= -width//2
ymin= -width*(3**0.5)//4
for n in range(nmax):
        turtle.penup()
        turtle.setposition(xmin,ymin)
        turtle.setheading(0)
        turtle.pencolor(colorsys.hls_to_rgb(1.0*n/6,0.5,1))
        turtle.pendown()
        arrow(n,256)

turtle.exitonclick()

16

def av(l):
        return sum(l)/len(l)

def rg(l):
        return max(l)-min(l)

def md(l):
        lx=len(l)
        ls=sorted(l)
        if lx%2:
                return ls[lx//2]
        else:
                return (ls[lx//2-1]+ls[lx//2])/2

if __name__=="__main__":
        l=input("dammi una lista di numeri separati da virgole (es: 1,2,3,4.4): ")
        l=[float(x) for x in l.split(',')]
        print("i valori trovati dalle tre funzioni sono: {:.4f} {:.4f} {:.4f}".format(av(l),rg(l),md(l)))

Carmela. Sono state dapprima definite tre funzioni. La prima, chiamata av, calcola un valore ottenuto dividendo la somma dei valori dei numeri inseriti dall’utente per quanti sono i numeri inseriti. La seconda funzione, chiamata rg, calcola la differenza tra il valore più grande e quello più piccolo dei numeri che sono stati inseriti. Infine, con l’ultima funzione md, data la lunghezza (lx) della lista dei numeri inseriti, li ordina con sorted, e pone la condizione che se il numero di elementi della lista è dispari, deve restituire il valore del numero che si trova nella posizione corrispondente al valore intero che si ottiene dividendo per due il numero di elementi della lista, altrimenti, deve restituire il valore che si ottiene dividendo per due la somma del valore del numero che si trova nella posizione corrispondente al numero che si ottiene dalla lunghezza della lista diviso due meno uno, con il valore del numero che si trova nella posizione corrispondente alla lunghezza della lista diviso due. Nella seconda parte del programma vi è la richiesta all’utente dei valori di input che andranno a costituire gli elementi della stringa ‘l’. Con l.split(‘,’) si indica che sarà restituita la lista degli elementi presenti nella stringa ‘l’ separati da virgola. Vi è infine il richiamo delle tre funzioni sopra definite. rd 9.06: La descrizione e' puntuale... manca solo l'ultimo passaggio. Questi tre valori sono importantissimi per la statistica, ognuno di questi ha un nome specifico. Cosa rappresentano questi tre valori relativamente alla lista data in input? Carmela: la funzione av calcola la media, la funzione rg calcola la dispersione, la funzione md dovrebbe calcolare la mediana (dico "dovrebbe" perché la statistica l'ho studiata quasi 20 anni fa)

17

import turtle
import sys

rows,cols=4,4
buttonsize=50
topdisplay=2*buttonsize

stack=[0]
fresh=True

def num(x):
        global fresh,stack
        if fresh:
                stack[:0]=[x]
                fresh=False
        else:
                stack[0]=stack[0]*10+x

enter,add,sub,mul,div=0,int.__add__,int.__sub__,int.__mul__,int.__floordiv__

def op(x):
        global fresh,stack
        if x!=enter and len(stack)>1:
                stack=[x(stack[1],stack[0])]+stack[2:]
        fresh=True

def off(x):
        sys.exit(0)

buttons={ 
        (0,0):('0',num,0), (1,0):('1',num,1), (1,1):('2',num,2), (1,2):('3',num,3), (2,0):('4',num,4), 
        (2,1):('5',num,5), (2,2):('6',num,6), (3,0):('7',num,7), (3,1):('8',num,8), (3,2):('9',num,9), 
        (3,3):('+',op,add), (2,3):('-',op,sub), (1,3):('*',op,mul), (0,3):('/',op,div),
        (0,2):('ent',op,enter), (0,1):('off',off,0)}

def click(x,y):
        col=x//buttonsize
        row=y//buttonsize
        if (row,col) in buttons:
                label,op,val=buttons[row,col]
                op(val)
                drawcalc()

def drawcalc():
        def drawbutton(col,row,label):
                turtle.setpos(row*buttonsize,col*buttonsize)
                turtle.pendown()
                for _ in range(4):
                        turtle.forward(buttonsize)
                        turtle.left(90)
                turtle.penup()
                turtle.setpos(row*buttonsize+buttonsize//2,col*buttonsize+buttonsize//2)
                turtle.write(label,align="center")
        turtle.clear()
        turtle.penup()
        for row,col in buttons:
                drawbutton(row,col,buttons[row,col][0])
        turtle.setpos(row*buttonsize*(rows-1),col*buttonsize*(cols+1))
        turtle.write(str(stack[0]),align="right")
        turtle.update()

turtle.screensize(cols*buttonsize+1, rows*buttonsize+topdisplay+1)
turtle.setup(cols*buttonsize+1, rows*buttonsize+topdisplay+1)
turtle.setworldcoordinates(0,0,cols*buttonsize, rows*buttonsize+topdisplay)
turtle.hideturtle()
turtle.speed(10)
turtle.tracer(0)
drawcalc()
turtle.onscreenclick(click)
turtle.listen()
turtle.mainloop()

18

import turtle
import colorsys
import time

N=6
frompin=list(range(N,0,-1))
auxpin=[]
topin=[]

def rectangle(size, level, pin):
        turtle.penup()
        turtle.setpos(2*N*10*pin,level*10)
        turtle.setheading(0)
        turtle.pendown()
        turtle.fillcolor(colorsys.hls_to_rgb(1.0*(size-1)/N,0.5,1))
        turtle.begin_fill()
        turtle.forward(size*10)
        turtle.left(90)
        turtle.forward(10)
        turtle.left(90)
        turtle.forward(size*20)
        turtle.left(90)
        turtle.forward(10)
        turtle.left(90)
        turtle.forward(size*10)
        turtle.end_fill()

def showhanoi():
        turtle.clear()
        lf,la,lt=map(len,(frompin,auxpin,topin))
        for i in range(lf):
                rectangle(frompin[i], i, -1)
        for i in range(la):
                rectangle(auxpin[i], i, 0)
        for i in range(lt):
                rectangle(topin[i], i, 1)
        turtle.update()
        time.sleep(0.2)

def hanoi(n,f,a,t):
        if n==1:
                t.append(f.pop())
                showhanoi()
        else:
                hanoi(n-1,f,t,a)
                hanoi(1,f,a,t)
                hanoi(n-1,a,f,t)

turtle.hideturtle()
turtle.speed(10)
turtle.tracer(0)
showhanoi()
hanoi(N,frompin,auxpin,topin)
turtle.exitonclick()
Strumenti personali
Namespace

Varianti
Azioni
Navigazione
Strumenti